import Router from 'koa-router';
// 使用redis 验证 --- 不同用户同时发送验证码 区分不用户,不能存表(量大,内存会溢出),
import Redis from 'koa-redis';
// 给用户发邮件
import nodeMailer from 'nodemailer';
import Email from '../dbs/config';
import userModel from '../dbs/models/user';
import axios from './utils/axios';
import passport from './utils/passport';
import { _err } from './utils/public'
const router = new Router({
  prefix: '/users'
});

const client = new Redis({}).client;


// 注册
router.post('/signup', async (ctx) => {
  const {
    username,
    password,
    email,
    code
  } = ctx.request.body;
  // 验证code
  if (code) {
    // 获取对应的code 验证码
    const saveCode = await client.hget(`nodemail:${username}`, 'code');
    // 过去时间
    const expire = await client.hget(`nodemail:${username}`, 'expire');
    if (code === saveCode) {
      // 是否过期
      console.log(Date.now(), expire)
      if (Date.now() - expire > 0) {
        ctx.body = {
          code: -1,
          msg: '验证码已过期,请重新验证'
        };
        return false;
      }
    } else {
      // 验证码错误
      ctx.body = {
        code: -1,
        msg: '验证码错误'
      };
    }
  } else {
    ctx.body = {
      code: -1,
      msg: '验证码不能为空'
    };
  }

  // 验证用户是否被注册过.
  const result = await userModel.findOne(username);
  if (result) {
    ctx.body = _err('用户名被注册过了');
  } else {
    let user = userModel.create({
      username,
      password,
      email
    });
    if (user) {
      // 注册后自动登录 注意有前缀
      let res = await axios.post('/users/signin', {
        username,
        password
      });
      
      if (res.data && res.data.code === 0) {
        ctx.body = {
          code: 0,
          data: res.data.user,
          msg: '注册成功'
        };
      } else {
        ctx.body = _err('error');
      }
    } else {
      // 创建失败
      ctx.body = _err('注册失败');
    }
  }
});

// 登录
router.post('/signin', (ctx, next) => {
  // 登录 验证
  const res = passport.authenticate("local", function (
    err,
    user,
    info
  ) {
    if (err) {
      ctx.body = _err(err);
      return next(err)
    }
    if (user) {
      ctx.body = {
        code: 0,
        msg: '登录成功',
        data: user
      };
      // passport 登录用户初始化session
      return ctx.login(user);
    } else {
      ctx.body = {
        code: 1,
        msg: info
      };
    }
  })(ctx, next);
  return res
});

// 验证
router.post('/verify', async (ctx, next) => {
  let {
    username,
    email
  } = ctx.request.body
  // 阻止频繁访问
  let expire = await client.hget(`nodemail:${username}`, 'expire');
  if (expire && (Date.now() - expire) < 0) {
    ctx.body = {
      code: -1,
      msg: '请求过于频繁'
    }
    return false
  }
  // 邮件配置
  let transporter = nodeMailer.createTransport({
    host: Email.smtp.host,
    post: Email.smtp.port,
    // 监听其他端口(原: 465)
    secure: false,
    auth: {
      user: Email.smtp.user,
      // 授权码
      pass: Email.smtp.pass
    }
  })
  // 新建一个验证码信息
  let ko = {
    code: Email.code(),
    expire: Email.expire(),
    user: username,
    email: email,
  }
  // 邮件信息配置
  let mailOptions = {
    from: `认证邮件<${Email.smtp.user}>`,
    to: ko.email,
    // 标题
    subject: `网站的注册码`,
    // 发送的text或者html格式
    html: `你的验证码是${ko.code}`
  }
  // 发送
  await transporter.sendMail(mailOptions, (error, info) => {
    if (error) {
      return console.log(error)
    }
    // hmset   为散列里面的一个或多个键设置值 OK  hmset('hash-key', obj)
    client.hmset(`nodemail:${ko.user}`, 'code', ko.code, 'expire', ko.expire, 'email', ko.email)
    
  })
  ctx.body = {
    code: 0,
    msg: `验证码已发送, 有效期 1 min`
  }
})

// ctx.isAuthenticated() 判断是否登录
router.get(`/exit`, async (ctx, next) => {
  // passport 删除该用户session 
  if (ctx.isAuthenticated()) {
    await ctx.logout()
  }
  // 二次验证是否退出 passport的验证 
  // isAuthenticated: 测试该用户是否存在于session中（即是否已登录）
  if (ctx.isAuthenticated()) {
    ctx.body = _err('退出失败')
  } else {
    ctx.body = {
      code: 0
    }
  }
})

// 获取用户信息
router.get('/getUser', async (ctx) => {
  if (ctx.isAuthenticated()) {
    let {
      username,
      email
    } = ctx.session.passport.user
    ctx.body = {
      code: 0,
      user: username,
      email
    }
  } else {
    ctx.body = {
      code: -1,
      user: '',
      email: ''
    }
  }
})

export default router
